* Date: 03/07/2018
* Written by: Mattia Chiapello

*! version 4.1  03jul2018  Mattia Chiapello

cap program drop balancetable_custom
program define balancetable_custom
	version 14.0
	syntax varlist [if] [in] using/, [replace robust NOSTARS format(string) displayformat addpanels(string asis) ///
		prehead(string asis) posthead(string asis) prefoot(string asis) postfoot(string asis)]
	marksample touse, novarlist
	tokenize `"`addpanels'"'

	* Create postfile
	tempname postBalance
	tempfile balance
	qui postfile `postBalance' Line str100 Variable str50 Group1Mean str50 Group1SD str50 Group2Mean str50 Group2SD str50 Group3Mean str50 Group3SD ///
		str50 Diff1Pval str5 Diff1Star str50 Diff2Pval str5 Diff2Star str50 Diff3Pval str5 Diff3Star using "`balance'", replace

	* Check presence of 'listtab' command
	cap which listtab
	if _rc ssc install listtab

	* Process format option
	if "`format'" == "" & "`displayformat'" == "" {
		local format = "%10.3fc"
		local pvalformat = "%10.3f"
	}
	else if "`format'" == "" & "`displayformat'" != "" local pvalformat = "%5.2f"
	else if "`format'" != "" & "`displayformat'" != "" {
		dis as error "Error: format and displayformat are alternative options and may not be used together"
		error 197
	}

	* Process addpanels option
	if `"`addpanels'"' != "" {
		local n_panels: word count `addpanels'
		if mod(`n_panels',2) != 0 {
			dis as error "Error: the option addpanels requires an even number of arguments"
			error 197
		}
		forvalues i = 1(2)`n_panels' {
			confirm variable ``i'', exact
		}
	}

	* Loop over the variables to build the table line by line
	local counter 0
	foreach x of local varlist {
		local ++counter

		* Add panel if required
		if `"`addpanels'"' != "" {
			forvalues i = 1(2)`n_panels' {
				if "`x'" == "``i''" & `counter' != 1 post `postBalance' (`counter') ("\addlinespace \multicolumn{10}{l}{\textbf{``=`i'+1''}}\\ %") ("") ("") ("") ("") ("") ("") ("") ("") ("") ("") ("") ("")
				else if "`x'" == "``i''" & `counter' == 1 post `postBalance' (`counter') ("\multicolumn{10}{l}{\textbf{``=`i'+1''}}\\ %") ("") ("") ("") ("") ("") ("") ("") ("") ("") ("") ("") ("")
			}
		}

		* Store variable label
		local variable: var label `x'
		local variable: subinstr local variable "_" "\_", all

		* Process displayformat option
		if "`displayformat'" != "" local format: format `x'

		* Compute means and SD and store them
		qui sum `x' if `touse' & treatment==0
		local gr1mean "`: dis `format' r(mean)'"
		local gr1sd "`: dis `format' r(sd)'"
		qui sum `x' if `touse' & t1==1
		local gr2mean "`: dis `format' r(mean)'"
		local gr2sd "`: dis `format' r(sd)'"
		qui sum `x' if `touse' & t2==1
		local gr3mean = "`: dis `format' r(mean)'"
		local gr3sd "`: dis `format' r(sd)'"

		* Run regressions and store p-values
		qui regress `x' t1 if `touse' & t2==0, `robust'
		qui test t1 = 0
		local diff1pval "`: dis `pvalformat' r(p)'"
		if "`nostars'"=="" {
			check_stars r(p)
			local diff1stars = s(stars)
		}
		qui regress `x' t2 if `touse' & t1==0, `robust'
		qui test t2 = 0
		local diff2pval "`: dis `pvalformat' r(p)'"
		if "`nostars'"=="" {
			check_stars r(p)
			local diff2stars = s(stars)
		}
		qui regress `x' t1 t2 if `touse', `robust'
		qui test t1 = t2 = 0
		local diff3pval "`: dis `pvalformat' r(p)'"
		if "`nostars'"=="" {
			check_stars r(p)
			local diff3stars = s(stars)
		}

		* Post result in postfile
		post `postBalance' (`counter') ("`variable'") ("`gr1mean'") ("`gr1sd'") ("`gr2mean'") ("`gr2sd'") ("`gr3mean'") ("`gr3sd'") ///
			("`diff1pval'") ("`diff1stars'") ("`diff2pval'") ("`diff2stars'") ("`diff3pval'") ("`diff3stars'")

	}
	postclose `postBalance'

	* Store the number of observations
	qui count if `touse' & treatment==0
	local group1obs = strtrim("`: dis %20.0gc r(N)'")
	qui count if `touse' & t1==1
	local group2obs = strtrim("`: dis %20.0gc r(N)'")
	qui count if `touse' & t2==1
	local group3obs = strtrim("`: dis %20.0gc r(N)'")

	* Edit "dataset"
	preserve
	use `balance', clear
	forvalues i = 1/3 {
		qui replace Diff`i'Star = "" if Diff`i'Star == "."
		qui replace Diff`i'Pval = Diff`i'Pval+Diff`i'Star
	}

	* Print out Latex table
	listtab Variable Group1Mean Group1SD Group2Mean Group2SD Group3Mean Group3SD Diff1Pval Diff2Pval Diff3Pval using "`using'", ///
		`replace' rstyle(tabular) head("\begin{tabular}{l*{9}{c}}" ///
		"\toprule" "&(1)&(2)&(3)&(4)&(5)&(6)&(7)&(8)&(9)\\" ///
		"&\multicolumn{2}{c}{Control group (C)}&\multicolumn{2}{c}{\makecell{Soft-skills \\ training (T1)}}&\multicolumn{2}{c}{\makecell{Combined \\ training (T2)}}&T1=C&T2=C&T1=T2=C\\" ///
		"\cmidrule(rl){2-3} \cmidrule(rl){4-5} \cmidrule(rl){6-7} \cmidrule(rl){8-8} \cmidrule(rl){9-9} \cmidrule(rl){10-10}" ///
		" & Mean & SD & Mean & SD & Mean & SD & P-val. & P-val. & P-val.\\" "\midrule") ///
		foot(`prefoot' "\midrule Observations & `group1obs' & & `group2obs' & & `group3obs' & & & & \\" ///
		"\bottomrule" `postfoot' "\end{tabular}")
	restore
end



* Small auxiliary program to check if p-values are significant and store stars in s(stars)
cap program drop check_stars
program define check_stars, sclass
	version 14.0
	syntax anything

	if `anything' < 0.01 sreturn local stars "***"
	else if `anything' < 0.05 sreturn local stars "**"
	else if `anything' < 0.10 sreturn local stars "*"
	else sreturn local stars ""
end

